home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assemblers / cas.lha / orig / ex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-15  |  13.0 KB  |  371 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include "io.h"
  5. #include "ex.h"
  6. #include "st.h"
  7. #include "res.h"
  8.  
  9. /* Derived from the syntax:
  10.    Ex = primary | unary Ex | Ex binary Ex | Ex "?" Ex ":" Ex | "(" Ex ")".
  11.    with the usual C-like precedence rules.
  12.  */
  13.  
  14. Exp ExpHead;
  15. static Exp ExpTail;
  16. static Exp ExpHash[0x100];
  17.  
  18. void ExpInit(void) {
  19.    int H;
  20.    ExpTail = ExpHead = 0;
  21.    for (H = 0; H < 0x100; H++) ExpHash[H] = 0;
  22. }
  23.  
  24. static byte Direct = 2; /* 0 = Absolute, 1 = Relative, 2 = Undefined */
  25.  
  26. #define STACK_MAX 100
  27.  
  28. typedef enum { BOT, PAR, COND, ELS, BIN, UN } StackTag;
  29.  
  30. static StackTag TStack[STACK_MAX], *TP;
  31. static Lexical OStack[STACK_MAX], *OP;
  32. static struct Exp EStack[STACK_MAX], *EP;
  33. static Exp AStack[STACK_MAX], *AP;
  34.  
  35. static void PUSH(StackTag Tag) {
  36.    if (TP >= TStack + STACK_MAX)
  37.       FATAL("Expression too complex ... aborting.");
  38.    *TP++ = Tag;
  39. }
  40.  
  41. static void PutE(Exp E) { if (Direct < 2) EP++; else *AP++ = E; }
  42. static Exp GetE(void) { return (Direct < 2)? --EP: *--AP; }
  43.  
  44. void MarkExp(Exp E) {
  45.    if (E->Map) return;
  46.    E->Map = 1;
  47.    switch (E->Tag) {
  48.       case NumX: case AddrX: break;
  49.       case SymX: SYM(E)->Map = 1; break;
  50.       case CondX:
  51.          MarkExp(ARG3(E));
  52.       case BinX:
  53.          MarkExp(ARG2(E));
  54.       case UnX:
  55.          MarkExp(ARG1(E));
  56.       break;
  57.    }
  58. }
  59.  
  60. Exp EvalExp(Exp E) {
  61.    ExpTag Tag = E->Tag;
  62.    Symbol Sym; Lexical Op; Exp A, B, C, E1; byte H, Bs;
  63.    Segment Seg; word Offset, Value, vB;
  64.    if (Phase == 1) {
  65.       if (E->Mark) return E;
  66.       StartLine = E->Line, StartF = E->File;
  67.    }
  68.    switch (Tag) {
  69.       case NumX: Value = VALUE(E); break;
  70.       case AddrX: Seg = SEG(E), Offset = OFFSET(E); break;
  71.       case SymX:
  72.          Sym = SYM(E);
  73.          if (!Sym->Defined) break;
  74.          else if (Sym->Address)
  75.             Tag = AddrX, Seg = Sym->Seg, Offset = Sym->Offset;
  76.          else
  77.             Tag = NumX, Value = Sym->Offset;
  78.       break;
  79.       case UnX:
  80.          Op = OP(E), A = ARG1(E);
  81.          if (Phase == 1) A = EvalExp(A);
  82.          if (Op == PLUS) return A;
  83.          switch (A->Tag) {
  84.             case AddrX:
  85.                ERROR("Address cannot be used with prefix operator.");
  86.                Tag = NumX; Value = SEG(A)->Base + OFFSET(A);
  87.             break;
  88.             case NumX: Tag = NumX; Value = VALUE(A); break;
  89.          }
  90.          if (Tag == NumX) switch (Op) {
  91.             case HIGH: Value = (Value >> 8)&0xff; break;
  92.             case LOW: Value = Value&0xff; break;
  93.             case NOT_NOT: Value = !Value; break;
  94.             case NOT: Value = ~Value; break;
  95.             case MINUS: Value = -Value; break;
  96.          }
  97.       break;
  98.       case BinX:
  99.          Op = OP(E), A = ARG1(E), B = ARG2(E);
  100.          if (Phase == 1) A = EvalExp(A), B = EvalExp(B);
  101.          if (Op == PLUS) {
  102.             if (A->Tag == NumX && B->Tag == NumX) {
  103.                Tag = NumX, Value = VALUE(A) + VALUE(B);
  104.             } else if (A->Tag == NumX && B->Tag == AddrX) {
  105.                Tag = AddrX, Seg = SEG(B), Offset = VALUE(A) + OFFSET(B);
  106.             } else if (A->Tag == AddrX && B->Tag == NumX) {
  107.                Tag = AddrX, Seg = SEG(A), Offset = OFFSET(A) + VALUE(B);
  108.             } else if (A->Tag == AddrX && B->Tag == AddrX) {
  109.                ERROR("Illegal combination: address + address");
  110.                Tag = AddrX, Seg = SEG(A), Offset = OFFSET(A) + OFFSET(B);
  111.             }
  112.          } else if (Op == MINUS) {
  113.             if (A->Tag == NumX && B->Tag == NumX) {
  114.                Tag = NumX, Value = VALUE(A) - VALUE(B);
  115.             } else if (A->Tag == NumX && B->Tag == AddrX) {
  116.                ERROR("Illegal combination: number - address");
  117.                Tag = NumX, Value = VALUE(A) - (SEG(B)->Base + OFFSET(B));
  118.             } else if (A->Tag == AddrX && B->Tag == NumX) {
  119.                Tag = AddrX, Seg = SEG(A), Offset = OFFSET(A) - VALUE(B);
  120.             } else if (A->Tag == AddrX && B->Tag == AddrX) {
  121.                if (SEG(A)->Type != SEG(B)->Type) {
  122.                   ERROR("Addresses of different types cannot be subtracted.");
  123.                   Tag = AddrX, Seg = SEG(A), Offset = OFFSET(A) - OFFSET(B);
  124.                } else if (SEG(A) == SEG(B))
  125.                   Tag = NumX, Value = OFFSET(A) - OFFSET(B);
  126.             }
  127.          } else if (Op == DOT) {
  128.             Tag = AddrX, Seg = SegTab + BIT;
  129.             switch (A->Tag) {
  130.                case NumX:
  131.                   Offset = VALUE(A);
  132.                XX:
  133.                   if ((Offset&0xfff0) == 0x20) Offset = (Offset - 0x20) << 3;
  134.                   else if ((Offset&0xff87) != 0x80)
  135.                      ERROR("Register in reg.bit not bit addressible."),
  136.                      Offset = 0;
  137.                break;
  138.                case AddrX:
  139.                   if (SEG(A)->Type != DATA && SEG(A)->Type != SFR)
  140.                      ERROR("Address of wrong type in reg.pos"), Offset = 0;
  141.                   else if (SEG(A)->Rel) {
  142.                      Tag = BinX; break;
  143.                   } else {
  144.                      Offset = SEG(A)->Base + OFFSET(A);
  145.                      if (SEG(A)->Type == DATA && Offset >= 0x80)
  146.                         ERROR("Indirect registers are not bit addressible."),
  147.                         Offset = 0;
  148.                   }
  149.                goto XX;
  150.                default: Tag = BinX; break;
  151.             }
  152.             if (Tag == AddrX) switch (B->Tag) {
  153.                case NumX:
  154.                   vB = VALUE(B);
  155.                   if (vB >= 8)
  156.                      ERROR("Bit position out of range."), vB &= 7;
  157.                break;
  158.                case AddrX:
  159.                   ERROR("Illegal combination: reg.bit"), vB = 0;
  160.                break;
  161.                default: Tag = BinX; break;
  162.             }
  163.             if (Tag == AddrX) Offset += vB;
  164.          } else {
  165.             Tag = NumX;
  166.             if (A->Tag == AddrX || B->Tag == AddrX)
  167.                ERROR("Address cannot be used with infix operator.");
  168.             else if (A->Tag != NumX && B->Tag != NumX) Tag = BinX;
  169.             if (Tag == NumX) {
  170.                Value = A->Tag == NumX? VALUE(A): OFFSET(A),
  171.                vB = B->Tag == NumX? VALUE(B): OFFSET(B);
  172.                switch (Op) {
  173.                   case BY: Value = (Value << 8) | (vB&0xff); break;
  174.                   case OR_OR: if (vB) Value = 1; break;
  175.                   case AND_AND: if (!vB) Value = 0; break;
  176.                   case OR: Value |= vB; break;
  177.                   case XOR: Value ^= vB; break;
  178.                   case AND: Value &= vB; break;
  179.                   case SHL: Value <<= vB; break;
  180.                   case SHR: Value >>= vB; break;
  181.                   case MULT: Value *= vB; break;
  182.                   case EQ: Value = Value == vB; break;
  183.                   case NE: Value = Value != vB; break;
  184.                   case LE: Value = Value <= vB; break;
  185.                   case LT: Value = Value < vB; break;
  186.                   case GE: Value = Value >= vB; break;
  187.                   case GT: Value = Value > vB; break;
  188.                   case DIV:
  189.                      if (vB == 0) ERROR("Division by 0."), Value = -1;
  190.                      else Value /= vB;
  191.                   break;
  192.                   case MOD:
  193.                      if (vB == 0) ERROR("Modulo by 0."), Value = -1;
  194.                      else Value %= vB;
  195.                   break;
  196.                }
  197.             }
  198.          }
  199.       break;
  200.       case CondX:
  201.          A = ARG1(E), B = ARG2(E), C = ARG3(E);
  202.          if (Phase == 1) A = EvalExp(A), B = EvalExp(B), C = EvalExp(C);
  203.          if (A->Tag == AddrX) {
  204.             ERROR("Address cannot appear in: x? x: x"); return C;
  205.          } else if (A->Tag != NumX) Tag = CondX;
  206.          else return EvalExp((VALUE(A))? B: C);
  207.       break;
  208.    }
  209.    if (Direct < 2) {
  210.       if (Tag == AddrX) {
  211.          if (Direct == 0) {
  212.             if (Seg->Rel) ERROR("Relative address cannot be used here");
  213.             Tag = NumX, Value = Seg->Base + Offset;
  214.          }
  215.       } else {
  216.          if (Tag == SymX)
  217.             ERROR("Undefined symbol: %s", Sym->Name), Tag = NumX, Value = 0;
  218.          else if (Tag != NumX)
  219.             ERROR("Undefined expression"), Tag = NumX, Value = 0;
  220.       }
  221.       if (Tag == NumX)
  222.          EP->Tag = NumX, VALUE(EP) = Value;
  223.       else
  224.          EP->Tag = AddrX, SEG(EP) = Seg, OFFSET(EP) = Offset;
  225.       return EP;
  226.    }
  227.    Bs = Seg - SegTab;
  228.    if (Phase == 1) E1 = E;
  229.    switch (Tag) {
  230.       case NumX:
  231.          H = (Value^(Value>>6)^(Value>>12))&0x3f;
  232.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  233.             if (Value == VALUE(E)) return E;
  234.       break;
  235.       case AddrX:
  236.          H = (Bs^(Bs>>6)^Offset^(Offset>>6)^(Offset>>12))&0x3f|0x40;
  237.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  238.             if (Seg == SEG(E) && Offset == OFFSET(E)) return E;
  239.       break;
  240.       case SymX: {
  241.          char *S;
  242.          for (H = 0, S = Sym->Name; *S != '\0'; S++) H ^= *S;
  243.          H = H&0x3f|0x80;
  244.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  245.             if (Sym == SYM(E)) return E;
  246.       }
  247.       break;
  248.       case UnX:
  249.          H = (Op^(Op>>6)^A->Hash)&0xf|0xe0;
  250.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  251.             if (Op == OP(E) && A == ARG1(E)) return E;
  252.       break;
  253.       case BinX:
  254.          H = (Op^(Op>>6)^A->Hash^B->Hash)&0x1f|0xc0;
  255.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  256.             if (Op == OP(E) && A == ARG1(E) && B == ARG2(E)) return E;
  257.       break;
  258.       case CondX:
  259.          H = (A->Hash^B->Hash^C->Hash)&0xf|0xf0;
  260.          for (E = ExpHash[H]; E != 0; E = E->Tail)
  261.             if (A == ARG1(E) && B == ARG2(E) && C == ARG3(E)) return E;
  262.       break;
  263.    }
  264.    if (Phase == 1) E = E1, E->Mark = 1;
  265.    else {
  266.       E = (Exp)Allocate(sizeof *E);
  267.       E->Hash = H, E->Tail = ExpHash[H], ExpHash[H] = E;
  268.       E->Next = 0, E->Map = 0,
  269.       E->Line = StartLine, E->File = StartF,
  270.       E->Mark = (Phase == 0)? 0: 1;
  271.       if (ExpHead == 0) ExpHead = E; else ExpTail->Next = E;
  272.       ExpTail = E;
  273.    }
  274.    switch (E->Tag = Tag) {
  275.       case NumX: VALUE(E) = Value; break;
  276.       case AddrX: SEG(E) = Seg, OFFSET(E) = Offset; break;
  277.       case SymX: SYM(E) = Sym; break;
  278.       case UnX: OP(E) = Op, ARG1(E) = A; break;
  279.       case BinX: OP(E) = Op, ARG1(E) = A, ARG2(E) = B; break;
  280.       case CondX: ARG1(E) = A, ARG2(E) = B, ARG3(E) = C; break;
  281.    }
  282.    return E;
  283. }
  284.  
  285. static struct Exp EBuf;
  286. Exp MakeExp(ExpTag Tag, ...) {
  287.    va_list AP; Exp E = &EBuf;
  288.    if (!Active) return 0;
  289.    va_start(AP, Tag);
  290.    switch (E->Tag = Tag) {
  291.       case NumX: VALUE(E) = (word)va_arg(AP, unsigned); break;
  292.       case AddrX:
  293.          SEG(E) = va_arg(AP, Segment), OFFSET(E) = (word)va_arg(AP, unsigned);
  294.       break;
  295.       case SymX: SYM(E) = va_arg(AP, Symbol); break;
  296.       case UnX:
  297.          OP(E) = va_arg(AP, Lexical), ARG1(E) = va_arg(AP, Exp);
  298.       break;
  299.       case BinX:
  300.          OP(E) = va_arg(AP, Lexical), ARG1(E) = va_arg(AP, Exp),
  301.          ARG2(E) = va_arg(AP, Exp);
  302.       break;
  303.       case CondX:
  304.          ARG1(E) = va_arg(AP, Exp), ARG2(E) = va_arg(AP, Exp),
  305.          ARG3(E) = va_arg(AP, Exp);
  306.       break;
  307.    }
  308.    va_end(AP);
  309.    return EvalExp(E);
  310. }
  311.  
  312. #define uO 0x10
  313. /* Operator types: 20 = ), 40 = :, 60 = ?, 80 = binary */
  314. #define bO 0x80
  315. int OpTab[] = { /* Bits 0-3: precedence, Bit 4:unary, Bits 5-7: operator type */
  316.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  317.    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  318.    0x20, 0x40, 0x60,
  319.    uO, uO, uO, uO, uO|bO|2, uO|bO|2, bO|1, bO|1, bO|1,
  320.    bO|4, bO|4, bO|4, bO|4, bO|5, bO|5, bO|9, bO|10,
  321.    bO|6, bO|7, bO|8, bO|3, bO|3, bO, bO,
  322.    0, 0, 0, 0, 0
  323. };
  324.  
  325. char *Action[6] = {
  326. /*  .):?+ */
  327.    "...?+", /* BOT:     -> Exp $                 */
  328.    "B)B?+", /* PAR: Exp -> '(' Exp $ ')'         */
  329.    "AA:?+", /* COND Exp -> Exp '?' Exp $ ':' Exp */
  330.    "ccc?+", /* ELS: Exp -> Exp '?' Exp ':' Exp $ */
  331.    "bbbbC", /* BIN: Exp -> Exp bin Exp $         */
  332.    "uuuuu"  /* UN:  Exp -> un Exp $              */
  333. };
  334.  
  335. Exp Parse(int Dir) {
  336.    Lexical L = OldL; Symbol ID; Exp A, B; int Act;
  337.    InExp = 1; Direct = Dir;
  338.    EP = EStack, OP = OStack, AP = AStack, TP = TStack;
  339.    PUSH(BOT);
  340. EXP:
  341.    switch (L) {
  342.       case LPAR: PUSH(PAR); L = Scan(); goto EXP;
  343.       case NUMBER: A = MakeExp(NumX, Value); L = Scan(); goto END_EX;
  344.       case DOLLAR:
  345.          A = MakeExp(AddrX, SegP, (word)LOC); L = Scan();
  346.       goto END_EX;
  347.       case SYMBOL: A = MakeExp(SymX, Sym); L = Scan(); goto END_EX;
  348.       default:
  349.          if ((OpTab[L]&uO)) { PUSH(UN); *OP++ = L; L = Scan(); goto EXP; }
  350.          ERROR("Expected an argument/prefix operator.");
  351.          A = MakeExp(NumX, 0);
  352.       goto END_EX;
  353.    }
  354. END_EX:
  355.    Act = Action[*--TP][OpTab[L] >> 5];
  356.    if (Act == 'C')
  357.       Act = ((OpTab[L]&0x0f) < (OpTab[OP[-1]]&0x0f))? '+': 'b';
  358.    switch (Act) {
  359.       case '+': TP++; PUSH(BIN); *OP++ = L; PutE(A); L = Scan(); goto EXP;
  360.       case '?': TP++; PUSH(COND); PutE(A); L = Scan(); goto EXP;
  361.       case ':': PUSH(ELS); PutE(A); L = Scan(); goto EXP;
  362.       case 'A': ERROR("Missing ':'"); PUSH(ELS); PutE(A); goto EXP;
  363.       case ')': L = Scan(); goto END_EX;
  364.       case 'B': ERROR("Missing ')'"); goto END_EX;
  365.       case 'u': A = MakeExp(UnX, *--OP, A); goto END_EX;
  366.       case 'b': A = MakeExp(BinX, *--OP, GetE(), A); goto END_EX;
  367.       case 'c': B = GetE(); A = MakeExp(CondX, GetE(), B, A); goto END_EX;
  368.       case '.': InExp = 0, Direct = 2; return A;
  369.    }
  370. }
  371.